<?
    /* -*- Mode: PHP5; tab-width: 4; indent-tabs-mode: nil; basic-offset: 4 -*- */
    
    /*********************************************************
    *            --== InArch ==--
    *
    * This is the key class to all the client side data nodes.
    * It is extended into child classes which do all the work.
    *
    * @author Kulikov Alexey <a.kulikov@gmail.com>
    * @version n/a
    * @since 24.04.2005
    * @copyright essentialmind.com 2005
    *
    *********************************************************/
    
    /***
    * Abstract Class clientNode
    ****
    * Main purpose of this class is to handle all the template logic
    * any part of any client node may have. Moreover, this class is
    * responsible for the display of any child classes templates and
    * results. In other words, anything that reaches the browser
    * goes through this class!
    * 
    * This is an abstract class, meaning it has to be extended to add
    * the neccessary functionality. Base methods have already been
    * implemented and finalized.
    *
    * @2do -- get all page and node behvaiour into this class such that
    *         common procedures can be done in child classes with no
    *         code duplication
    ****
    * @package clientNodes
    * @author A Kulikov <a.kulikov@gmail.com>
    * @version n/a
    * @since 24.04.2005
    * @copyright essentialmind.com 2005
    ***/
    abstract class clientNode{
    
        /**
         * reference to the ADODB Connection
         *
         * @var ADOConnection
         */
        protected $db;      // 
        
        /**
         * reference to the template parser
         *
         * @var mySmarty
         */
        protected $smarty;  // 
        
        
        protected $action;  // name of the template on which the extension will be based on
        protected $log;     // reference to the log object
        
        /**
         * reference to the ID of the called page (if any)
         *
         * @var integer
         */
        protected $reference;

        /**
         * ID of the object which resolves to the data
         *
         * @var integer
         */
        protected $object;
        
        /**
         * ID of the node pointing to the object
         *
         * @var integer
         */
        protected $node;
        
        /**
         * Reference to a breadcrumbs object
         *
         * @var breadcrumbs
         */
        protected $crumbs;

        /* --------------- END VARIABLE DECLARATION ----------------- */
        
        /**
         * @param object $db     - Reference to the ADODB Connection
         * @param object $smarty - Reference to Smarty
         * @return void
         **/
        function __construct(ADOConnection $db, mySmarty $smarty, $log, breadcrumbs $crumbs){
            global $_CONFIG;
            
            $this->db       = $db;
            $this->smarty   = $smarty;
            $this->log      = $log;
            $this->crumbs   = $crumbs;

            //do we start a shopping cart?
            if($_CONFIG['shop']){
                if(!$_SESSION['CART'] or ($_SESSION['CART'] and !is_object($_SESSION['CART']))){
                    $_SESSION['CART'] = new shoppingCart($this->db);
                    
                    //redirect maybe?
                    
                    if(!$_GET['TID'] and $_CONFIG['redirect'] and !eregi('^'.$_CONFIG['redirect'],$_SERVER['HTTP_REFERER'])){
                        $hit = $this->db->getOne("SELECT country_code2 FROM countries WHERE ip_from <= ".ip2long($_SERVER['REMOTE_ADDR'])." AND ip_to >= ".ip2long($_SERVER['REMOTE_ADDR']));
                        if($_CONFIG['redirectif'] and $hit and !$_POST){
                            header('Location: '.$_CONFIG['redirect']);
                            exit;
                        }
                        //echo '<!-- '.$hit."SELECT country_code2 FROM countries WHERE ip_from >= ".ip2long($_SERVER['REMOTE_ADDR'])." AND ip_to <=".ip2long($_SERVER['REMOTE_ADDR']).' -->';
                    }
                    

                    //$_SESSION['CART'] = new shoppingCart($this->db);
                }
                $this->smarty->assign('CART',$_SESSION['CART']->smarty());
                $this->smarty->assign('CART_DATA',array(
                                                            'sum'       => $_SESSION['CART']->sum(),
                                                            'transport' => $_SESSION['CART']->getTransportCosts(),
                                                            'discount'  => $_SESSION['CART']->discount(),
                                                            'total'     => $_SESSION['CART']->price()
                                                        ));
            }
        }
        

        /**
         * Method signature. Forces the child class to implement
         * this method, which will set the HTML template needed for
         * the child's operation
         * 
         * @return 
         **/
        abstract protected function setTemplate();
        
        
        /**
         * Method Signature. Forces the child class to implement
         * a data processor.
         * 
         * @return 
         **/
        abstract protected function process();
        
        
        
        /**
         * Sets the references to data that is to be fetched from the DB
         * 
         * @param integer $object  - ID of the data object 
         * @param integer $node    - ID of the node referencing the object 
         * @return void
         **/
        final public function setReferences($object, $node=null, $reference=null){
            $this->object       = (int)$object;
            $this->node         = (int)$node;
            $this->reference    = (int)$reference;
        }
        

        /**
         * Sets the name of an action template
         * 
         * @param string $action - Name of the action template to be used
         * @return void
         **/
        final protected function setActionTemplate($action){
            $this->action = $action;
        }


        /**
         * Returs the name of the currently set action template
         * 
         * @return string
         **/
        final protected function getActionTemplate(){
            return $this->action;
        }
        
        
        /***
         *  @purpose    To tag a piece of content (PAGE!!!!)
         ***/
        protected function addTag($tag,$page=null){
            //double check
            if(!$page){
                $page = $this->reference;
            }
            
            if(!$page){
                return;
            }
            
            //yo!
            $tag = trim($tag);
            
            //make sure there is no empty tag mon
            if(empty($tag)){
                $tag = 'n/a';
            }

            
            //transliterate tag
            $myTranslit = new translitWrap();
            $name       = $myTranslit->UrlTranslit($tag);

            //is there THIS tag in the DB already?
            if(!$tagID = $this->db->getOne("SELECT id FROM tags WHERE url = ".$this->db->qstr($name))){
                $this->db->Execute("INSERT INTO tags(name, url) VALUES(".$this->db->qstr($tag).",".$this->db->qstr($name).")");
                $tagID = $this->db->getOne("select last_value from tags_id_seq");
            }
            

            //create a map reference (if needed)
            if(!$this->db->getOne("SELECT page_id FROM tag_page_map WHERE page_id = ".(int)$page." AND tag_id = ".(int)$tagID)){
                $this->db->Execute("INSERT INTO tag_page_map(tag_id, page_id) VALUES(".(int)$tagID.",".(int)$page.")");
            }
        }
        
        
        /*
         ------------------ Page Manipulation -------------------
         |
        */
        
        protected function getPageData(){
            //happens only in case there is a page reference, of course!
            if($this->reference > 0){
                $data         = $this->db->getRow("SELECT * FROM pagemap WHERE id = ".$this->reference);
                $data['tags'] = $this->db->getAll("SELECT 
                                                        tags.name, tags.url 
                                                        FROM tag_page_map 
                                                        LEFT JOIN tags ON tag_page_map.tag_id = tags.id 
                                                        WHERE tag_page_map.page_id = ".$this->reference);
                return $data;
            }
            return array();
        }
        
        /*
         |
         ---------------- / End Page Manipulation ----------------
        */

        
        /*
         ------------------ Node Manipulation -------------------
         |
        */
        
        /*
         |
         ---------------- / End Node Manipulation ----------------
        */
        
        
        /**
         * @param string $template - name of base template
         * @return 
         **/
        final function display($template='index.html',$cacheID=null){
            //rss exception
            if($_GET['rss']){
                $template='rss.html';
            }
            
            //set the child's action template      
            $this->setTemplate();

            try{
                //run the class' data processor and
                //process actions, such as GET and POST requests
                $this->process();
            }catch(Exception $e){
                //record error
                $this->log->recordError($e->getMessage());
                
                //redirect browser to tech error page
                
            }  
            
            //check if the action space exists
            if(!$this->smarty->template_exists($this->getActionTemplate())){
                throw new Exception('The defined action template "'.$this->getActionTemplate().'" does not exist!',4);
            }
            
            //all went fine, thus assign the action template to smarty
            $this->smarty->assign('action',$this->getActionTemplate());
            
            //image store path
            $this->smarty->assign('storePath',$this->getStorePath());
            
            //also pass the breadcrumbs array to smarty
            $this->smarty->assign('breadcrumbs',$this->crumbs->getCrumbs());
            
            //and all the IDs
            $this->smarty->assign('references', array(
                                                        'object' => $this->object,
                                                        'node'   => $this->node,
                                                        'reference' => $this->reference
                                                    ));
            
            //error check is done, lets do the template magic!
            $this->smarty->display($template,$cacheID);
        }
        
        
        final function getStorePath(){
            if(!$this->reference){
                $filePath = 'files'.DIRECTORY_SEPARATOR.'nodes'.DIRECTORY_SEPARATOR.$this->node.DIRECTORY_SEPARATOR;
            }else{                
                $pageType = $this->db->getOne("SELECT pagetype FROM pagemap WHERE id = ".$this->reference);
                $filePath = 'files'.DIRECTORY_SEPARATOR.'pages'.DIRECTORY_SEPARATOR.$pageType.'__'.$this->object.DIRECTORY_SEPARATOR;
            }
            return $filePath;
        }
    }
?>